#include <iostream>
using namespace std;

#include <list>
#include <vector>
#include <algorithm>

// int main()
// {
// 	int i = 0;
// 	const int ci = 0;
// 	const int& rci = ci;

// 	decltype(i) n;
// 	decltype(i) m = 1; // m的类型是int
// 	decltype(ci) x = 1; // x的类型是const int
// 	m++;
// 	//x++; // 报错

// 	decltype(rci) y = x; // y的类型是const int&
// 	// y++; // 报错
// 	// decltype(rci) z; // 报错

// 	int* p1 = &i;
// 	decltype(p1) p2 = nullptr; // p2的类型是int*

// 	// 特殊处理
// 	decltype(*p1) r1 = i; // r1的类型是int&，解引用表达式推导出的内容是引用
// 	decltype(i) r2; // r2的类型是int
// 	decltype((i)) r3 = i; // r3的类型是int&, (i)是一个表达式，变量是一种可以赋值的特殊表达式，所以会推出引用类型
// 	r1++;
// 	r3++;

// 	return 0;
// }

//#include <vector>
//using namespace std;
//template <typename T>
//class A
//{
//public:
//	void func(T& container)
//	{
//		_it = container.begin();
//	}
//private:
//	// 这里不确定是iterator还是const_iterator，也不能使用auto
//	//typename T::iterator _it;
//	// 使用decltype推导就可以很好的解决问题
//	decltype(T().begin()) _it;
//};
//
//int main()
//{
//	const vector<int> v1;
//	A<const vector<int>> obj1;
//	obj1.func(v1);
//	vector<int> v2;
//	A<vector<int>> obj2;
//	obj2.func(v2);
//
//	return 0;
//}

//template<class R, class Iter>
//R Func(Iter it1, Iter it2)
//{
//	R x = *it1;
//	++it1;
//	while (it1 != it2)
//	{
//		x += *it1;
//		++it1;
//	}
//	return x;
//}

template<class R, class Iter>
auto Func(Iter it1, Iter it2)
{
	auto x = *it1;
	++it1;
	while (it1 != it2)
	{
		x += *it1;
		++it1;
	}
	return x;
}

//int main()
//{
//	vector<int> v = { 1,2,3 };
//	list<string> lt = { "111","222","333" };
//	// 这里无法调用上面的函数，因为函数模板只能通过实参推导模板类型，无法推导R
//	//auto ret1 = Func(v.begin(), v.end());
//	//auto ret2 = Func(lt.begin(), lt.end());
//
//	// 显示实例化能解决问题，但是调用就很麻烦
//	auto ret1 = Func<decltype(*v.begin())>(v.begin(), v.end());
//	auto ret2 = Func<decltype(*lt.begin())>(lt.begin(), lt.end());
//
//	cout << ret1 << endl;
//	cout << ret2 << endl;
//}

//int main()
//{
//	int i = 0;
//	int& ri = i;
//	const int ci = 42; // 顶层const
//	int* const p1 = &i; // 顶层const
//	const int* p2 = &ci; // 底层const
//
//	auto j = ri; // j类型为int
//	decltype(auto) j1 = ri; // j1类型为int&
//	++j1;
//
//	auto r1 = ci; // r1类型为int，忽略掉顶层const
//	decltype(auto) rr1 = ci; // rr1类型为const int
//	r1++;
//	//rr1++;
//
//	auto r2 = p1; // r2类型为int*，忽略掉顶层const
//	decltype(auto) rr2 = p1; // rr1类型为int* const
//	r2++;
//	//rr2++;
//
//	auto r3 = p2; // r3类型为const int*，保留底层const
//	decltype(auto) rr3 = p2; // rr3类型为const int*
//	// (*rr3)++;
//
//	return 0;
//}